#pragma once

#include <queue>
#include "SFML/System.hpp"
#include "../Vocoder/Vocoder.h"
#include "../SAPIAdapter/SAPIEventCallback.h"
#include "../SAPIAdapter/StreamReceiver.h"
#include "../SAPIAdapter/SAPIController.h"

/*
Implements Modulator using callbacks from SAPIAdapter
*/
class SAPIModulator :
	public Modulator,
	public SAPIEventCallback,
	public StreamReceiver
{
public:
	SAPIModulator(void);
	~SAPIModulator(void);

	/*
	Use sapiController to create the next speech utterance and to switch voices
	*/
	SAPIController sapiController;

	/*
	voiceName refers to enumerated SAPI voices (see SAPIAdapter/VoiceNames.h).
	NULL means that the default voice will be used.
	*/
	void Initialize(unsigned int sampleRate, unsigned int windowLength, WCHAR* voiceName);

	/*
	Modulator implementation, uses samples received in NewSample.
	Returns false when NotifySAPIEventCallback/NewSample have gathered the last bits from the last speaking operation
	*/
	bool NextModulatorSample(short* output, unsigned int length, std::vector<SampleMarker>* markersReceiver);

	/*
	SAPIEventCallback implementation that receives sapi speech generation events that are used for markers as well as to determine when an utterance is complete
	*/
	void NotifySAPIEventCallback(CSpEvent* e);

	/*
	StreamReceiver implementation that receives generated spech
	*/
	void NewSample(short* sample, unsigned int length);


private:
	sf::Mutex mutex;
	unsigned int windowLength;
	std::queue<short> samples;
	bool endReceived;
};
